package com.ccteam.admin.view.fragments.album

import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.Fragment
import androidx.fragment.app.setFragmentResultListener
import androidx.fragment.app.viewModels
import androidx.lifecycle.lifecycleScope
import androidx.navigation.fragment.findNavController
import androidx.paging.LoadState
import androidx.paging.PagingDataAdapter
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import com.ccteam.admin.REFRESH_REQUEST_KEY
import com.ccteam.admin.core.ADD_TYPE
import com.ccteam.admin.core.EDIT_TYPE
import com.ccteam.admin.databinding.AlbumHomeInfoItemBinding
import com.ccteam.admin.databinding.FragmentAlbumHomeBinding
import com.ccteam.admin.viewmodels.album.AlbumHomeViewModel
import com.ccteam.model.album.AlbumVO
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch

@AndroidEntryPoint
class AlbumHomeFragment : Fragment() {

    private var _binding: FragmentAlbumHomeBinding? = null
    private val binding get() = _binding!!

    private val albumHomeViewModel by viewModels<AlbumHomeViewModel>()

    private lateinit var adapter: AlbumListRVAdapter

    companion object{
        val differCallback = object: DiffUtil.ItemCallback<AlbumVO>(){

            override fun areItemsTheSame(oldItem: AlbumVO, newItem: AlbumVO): Boolean {
                return oldItem == newItem
            }

            override fun areContentsTheSame(oldItem: AlbumVO, newItem: AlbumVO): Boolean {
                return oldItem == newItem
            }

        }
    }

    override fun onCreateView(
        inflater: LayoutInflater, container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        _binding = FragmentAlbumHomeBinding.inflate(inflater,container,false)
        return binding.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        binding.btnAdd.setOnClickListener {
            findNavController().navigate(AlbumHomeFragmentDirections
                .actionAlbumHomeFragmentToAlbumEditFragment(ADD_TYPE,null))
        }

        adapter = AlbumListRVAdapter(itemCallback)
        binding.rvAlbumList.adapter = adapter

        viewLifecycleOwner.lifecycleScope.launch {
            albumHomeViewModel.albumListFlow.collectLatest {
                adapter.submitData(it)
            }
        }

        binding.refreshView.setOnRefreshListener {
            adapter.refresh()
        }

        viewLifecycleOwner.lifecycleScope.launch {
            adapter.loadStateFlow.collectLatest { state ->
                binding.statusView.changeToLoadingStatus(state.refresh is LoadState.Loading)
                binding.statusView.changeToErrorStatus(state.refresh,
                    state.append.endOfPaginationReached && adapter.itemCount < 1)
                binding.refreshView.isRefreshing = state.refresh is LoadState.Loading
            }
        }

        binding.statusView.setRetryClickListener {
            adapter.retry()
        }
    }

    override fun onResume() {
        super.onResume()

        setFragmentResultListener(REFRESH_REQUEST_KEY) { _, bundle ->
            if(bundle.getBoolean(REFRESH_REQUEST_KEY)){
                viewLifecycleOwner.lifecycleScope.launch {
                    delay(100L)
                    adapter.refresh()
                }
            }
        }
    }

    private val itemCallback = object: AlbumItemClicked{

        override fun editItemClick(item: AlbumVO) {
            findNavController().navigate(AlbumHomeFragmentDirections
                .actionAlbumHomeFragmentToAlbumEditFragment(EDIT_TYPE,item.id))
        }

        override fun editItemMusicClick(item: AlbumVO) {
            findNavController().navigate(AlbumHomeFragmentDirections
                .actionAlbumHomeFragmentToAlbumMusicEditFragment(item.id,item.name))
        }

    }

    /**
     * 基于分页 [PagingDataAdapter] 的RecyclerView 适配器
     */
    class AlbumListRVAdapter(
        val callback: AlbumItemClicked
    ): PagingDataAdapter<AlbumVO, AlbumListRVAdapter.AlbumInfoViewHolder>(
        differCallback){

        inner class AlbumInfoViewHolder(
            val binding: AlbumHomeInfoItemBinding
        ): RecyclerView.ViewHolder(binding.root){
            var item: AlbumVO? = null
            init {

                binding.root.setOnClickListener {
                    item?.let {
                        callback.editItemClick(it)
                    }
                }
                binding.btnMusicInfoEdit.setOnClickListener {
                    item?.let {
                        callback.editItemClick(it)
                    }
                }
                binding.tvAlbumMusicEdit.setOnClickListener {
                    item?.let {
                        callback.editItemMusicClick(it)
                    }
                }
            }
        }

        override fun onBindViewHolder(holder: AlbumInfoViewHolder, position: Int) {
            val item = getItem(position)
            holder.item = item

            holder.binding.tvAlbumName.text = item?.name
            holder.binding.tvAlbumArtist.text = item?.artistName
            Glide.with(holder.binding.ivAlbum)
                .load(item?.imgUrl)
                .into(holder.binding.ivAlbum)
        }

        override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): AlbumInfoViewHolder {
            return AlbumInfoViewHolder(AlbumHomeInfoItemBinding.inflate(LayoutInflater.from(parent.context),parent,false))
        }
    }


    /**
     * Album列表点击事件回调
     */
    interface AlbumItemClicked{
        /**
         * 点击了编辑专辑信息
         */
        fun editItemClick(item: AlbumVO)

        /**
         * 点击了编辑专辑歌曲
         */
        fun editItemMusicClick(item: AlbumVO)
    }

    override fun onDestroyView() {
        super.onDestroyView()

        _binding = null
    }
}